package com.ruoyi.iot.exchange;

import com.alibaba.fastjson.JSON;
import com.ruoyi.iot.domain.IotFrame;
import com.ruoyi.iot.domain.vo.ProjectVO;
import com.ruoyi.iot.domain.vo.exchange.ProjectFrameDTO;
import com.ruoyi.iot.exchange.network.tcp.TcpNetty;
import com.ruoyi.iot.exchange.network.tcp.cache.TcpChannelCache;
import com.ruoyi.iot.exchange.network.tcp.handler.TCPDispatchHandlerFactory;
import com.ruoyi.iot.exchange.network.tcp.handler.TCPDispatchHandlerGatherProxy;
import com.ruoyi.iot.exchange.network.tcp.handler.dispatch.TCPDispatchHandler;
import com.ruoyi.iot.exchange.network.tcp.handler.impl.HexDataDispatchHandler;
import com.ruoyi.iot.feign.IExchangeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

@Service
@RequestMapping
@Slf4j
public class IotExchangeServiceImpl implements IExchangeService {

    /**
     * netty保存产品id，和task任务的接口
     */
    ConcurrentHashMap<Long, TcpNetty> nettyTask = new ConcurrentHashMap<>();

    /**
     * 服务池
     */
    ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(8);

   // @Autowired
  //  RedisProductCache redisProductCache;




    @Override
    public Boolean devOnline(String devNum) {

        Boolean rst = TcpChannelCache.getChannel(devNum) != null;

        return rst;
    }

    @Override
    public void startProjectServer(ProjectFrameDTO projectFrameDTO) {

        TcpNetty tcpNetty = nettyTask.get(projectFrameDTO.getProjectId());
        if(tcpNetty != null) {
          log.info(String.format("product:name=>%s running!", projectFrameDTO.getProjectName()));
          return;
        }

        TCPDispatchHandlerGatherProxy tcpDispatchHandlerGatherProxy = new TCPDispatchHandlerGatherProxy();

        List<IotFrame> frameDTOs = projectFrameDTO.getFrames();
        log.info("iot frames:" + JSON.toJSONString(frameDTOs));
        frameDTOs.forEach(frame -> {
            TCPDispatchHandler tcpDispatchHandler = TCPDispatchHandlerFactory.create(frame);
            if(tcpDispatchHandler == null) {
                log.info("null handler type:" + frame.getType());
            }
            tcpDispatchHandlerGatherProxy.addHandler(tcpDispatchHandler);
        });
        tcpNetty = new TcpNetty( projectFrameDTO.getTransport().intValue(), tcpDispatchHandlerGatherProxy);
        nettyTask.put(projectFrameDTO.getProjectId(), tcpNetty);
        executorService.execute(tcpNetty);
        log.info(String.format("product:id=>%s name=>%s start!", projectFrameDTO.getProjectId(),
                projectFrameDTO.getProjectName()));
       // redisProductCache.saveProjectServer(projectFrameDTO);

    }


    @Override
    public void stopProjectServer(ProjectVO projectVO) {
        Long projectId = projectVO.getProjectId();
        TcpNetty tcpNetty = nettyTask.get(projectId);

        if (tcpNetty != null) {
            tcpNetty.cancel();
          //  redisProductCache.removeProjectServer(projectId);
            nettyTask.remove(projectId);
            log.info(String.format("product id: %s stop!",projectId));
        }
    }



//    @PostConstruct
//    public void restartProjectServer() {
//        redisProductCache.getProjectServer().forEach(item -> {
//            startProjectServer(item);
//        });
//    }





}
